using System;
using System.Collections.Generic;
using System.Text;
using Sedna.Core.Persistence;
using Sedna.Domain;
using Iesi.Collections;
using NHibernate;
using Nullables;

namespace Sedna.API.Filter
{
    [Serializable]
    public class UserFilter: AbstractFilterState, IHqlQueryFilterState
    {
        private string username;
        private string firstName;
        private string lastName;
        private string phone;
        private string email;
        private NullableDateTime passwordExpiresFrom;
        private NullableDateTime passwordExpiresTo;
        private ISet roles = new HashedSet();

        #region Properties

        public ISet Roles
        {
            get { return roles; }
        }

        public NullableDateTime PasswordExpiresFrom
        {
            get { return passwordExpiresFrom; }
            set { passwordExpiresFrom = value; }
        }

        public NullableDateTime PasswordExpiresTo
        {
            get { return passwordExpiresTo; }
            set { passwordExpiresTo = value; }
        }

        public string Username
        {
            get { return username; }
            set { username = value; }
        }

        public string FirstName
        {
            get { return firstName; }
            set { firstName = value; }
        }

        public string LastName
        {
            get { return lastName; }
            set { lastName = value; }
        }

        public string Phone
        {
            get { return phone; }
            set { phone = value; }
        }

        public string Email
        {
            get { return email; }
            set { email = value; }
        }

        #endregion

        public IQuery ToHqlQuery(ISession session)
        {
            HqlQueryBuilder builder = new HqlQueryBuilder();
            builder.From.Add("User as user");
            builder.Like("user.Username", username)
                .Like("user.FirstName", firstName)
                .Like("user.LastName", lastName)
                .Like("user.Phone", phone)
                .Like("user.Email", email)
                .Between("user.PasswordExpires", passwordExpiresFrom, passwordExpiresTo);
            
            if (roles.Count != 0)
            {
                builder.Distinct = true;
                builder.Select.Add("user");
                builder.From.Add("Role as role");
                builder.Raw("role = any elements(user.Roles)");
                builder.In("role", Roles);
            }

            return builder.ToQuery(session);
        }
    }
}
